package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.ContractStatus;
import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.mapper.AdminContractDetailMapper;
import com.ygqh.baby.mapper.AdminContractMapper;
import com.ygqh.baby.po.AdminContract;
import com.ygqh.baby.po.AdminContractDetail;
import com.ygqh.baby.po.AdminContractDetailExample;
import com.ygqh.baby.po.AdminContractExample;
import com.ygqh.baby.po.YgGroup;
import com.ygqh.baby.service.AdminContractDetailService;
import com.ygqh.baby.service.AdminContractService;
import com.ygqh.baby.service.YgGroupService;
import com.ygqh.baby.service.YgSkuMaterialService;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class AdminContractServiceImpl implements AdminContractService {

	@Autowired
	private AdminContractMapper adminContractMapper;
	@Autowired
	private AdminContractDetailMapper adminContractDetailMapper;
	@Autowired
	private AdminContractDetailService adminContractDetailService;
	@Autowired
	private YgSkuMaterialService ygSkuMaterialService;
	@Autowired
	private YgGroupService ygGroupService;
	

	@Override
	public List<AdminContract> find() {
		AdminContractExample example = new AdminContractExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return adminContractMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		AdminContractExample example = new AdminContractExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return adminContractMapper.countByExample(example);
	}

	@Override
	public AdminContract findById(Long id) {
		return adminContractMapper.selectByPrimaryKey(id);
	}

	@Override
	public AdminContract findByCode(String code) {
		AdminContractExample example = new AdminContractExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andContractCodeEqualTo(code).andContractStatusNotEqualTo(ContractStatus.Cancel.name());
		List<AdminContract> list = adminContractMapper.selectByExample(example);
		if (list.size() == 1)
			return list.get(0);

		return null;
	}

	@Override
	public int save(AdminContract adminContract, String operator) {
		int result;

		adminContract.setCreateBy(operator);
		adminContract.setCreateTime(new Date());
		adminContract.setContractStatus(ContractStatus.NotArchived);
		adminContract.setStatus(DataStatus.Valid);
		result = adminContractMapper.insertSelective(adminContract);
		List<AdminContractDetail> details = adminContract.getContractDetails();
		details.forEach(e -> {
			e.setContractId(adminContract.getId());
			e.setStatus(DataStatus.Valid);
		});
		adminContractDetailMapper.saveBatch(details);
		return result;
	}

	@Override
	public int update(AdminContract adminContract) {

		return adminContractMapper.updateByPrimaryKeySelective(adminContract);
	}

	@Override
	public int update(AdminContract adminContract, String operator) {
		adminContract.setUpdateTime(new Date());
		adminContract.setUpdateBy(operator);

		List<Long> dbAdminContractDetailIds = this.findDetailById(adminContract.getId()).getContractDetails().stream().map(e -> e.getId())
				.collect(Collectors.toList());
		adminContractDetailService.deleteSoft(dbAdminContractDetailIds.toArray(new Long[] {}));
		List<AdminContractDetail> details = adminContract.getContractDetails();
		details.forEach(e -> {
			e.setContractId(adminContract.getId());
			e.setStatus(DataStatus.Valid);
		});
		adminContractDetailMapper.saveBatch(details);
		return adminContractMapper.updateByPrimaryKeySelective(adminContract);
	}

	@Override
	public ResultSet<AdminContract> search(QueryInfo queryInfo, String q, Date startDate, Date endDate, ContractStatus contractStatus,
										   String contractType,String productName,String contractCode, String skuCode) {
		List<AdminContract> list = adminContractMapper.selectSuper(queryInfo, q, contractStatus, startDate, endDate, contractType,
				productName,contractCode, skuCode);
		int count = adminContractMapper.countSuper(q, contractStatus, startDate, endDate, contractType,productName,contractCode, skuCode);
		ResultSet<AdminContract> resultSet = new ResultSet<>(count, list);
		return resultSet;
	}

	@Override
	public List<AdminContract> findContractListBySupplier(Long supplierId) {
		AdminContractExample example = new AdminContractExample();
		List<String> status = new ArrayList<String>();
		status.add(ContractStatus.Archived.name());
		status.add(ContractStatus.Buying.name());
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andSupplierIdEqualTo(supplierId).andContractStatusIn(status);
		return adminContractMapper.selectByExample(example);
	}

	@Override
	public AdminContract findDetailById(Long id) {
		return adminContractMapper.findDetailById(id);
	}

	@Override
	public Message deleteContract(Long id, String operator) {
		AdminContract adminContract = this.findById(id);
		// 如果不是未归档
		if (!adminContract.getContractStatus().name().equals(ContractStatus.NotArchived.name())) {
			return Message.error("删除失败，合同状态必须为未归档");
		}
		List<Long> dbAdminContractDetailIds = this.findDetailById(id).getContractDetails().stream().map(e -> e.getId()).collect(Collectors.toList());
		adminContractDetailService.deleteSoft(dbAdminContractDetailIds.toArray(new Long[] {}));
		this.deleteSoft(id);
		return Message.success("操作成功");
	}

	@Override
	public Message updateContractStatus(Long id, String operator, ContractStatus contractStatus) {
		AdminContract adminContract = this.findById(id);
		adminContract.setContractStatus(contractStatus);
		adminContract.setUpdateBy(operator);
		adminContract.setUpdateTime(new Date());
		adminContractMapper.updateByPrimaryKey(adminContract);
		return Message.success("操作成功");
	}

	@Override
	public Message updateRemark(Long id, String operator, String remark) {
		AdminContract adminContract = findById(id);
		adminContract.setRemark(remark);
		adminContract.setUpdateBy(operator);
		adminContract.setUpdateTime(new Date());
		adminContractMapper.updateByPrimaryKeyWithBLOBs(adminContract);
		return Message.success("操作成功");
	}

	@Override
	public Message archivedContract(Long id, String operator, String contractCode) {
		
		AdminContract contract = this.findByCode(contractCode);
		if (contract!=null)
			return Message.error("合同号已经存在");

		AdminContract adminContract = this.findById(id);
		adminContract.setContractStatus(ContractStatus.Archived);
		adminContract.setUpdateBy(operator);
		adminContract.setContractCode(contractCode);
		adminContract.setUpdateTime(new Date());
		adminContractMapper.updateByPrimaryKey(adminContract);
		setSkuCost(id);
		return Message.success("操作成功");
	}
	@Override
	public void setSkuCost(Long contractId){
		ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
		    fixedThreadPool.execute(new Runnable() {
		        @Override
		        public void run() {
		            List<AdminContractDetail> adminContractDetails=adminContractDetailService.findSkuListByContractId(contractId);
		            ygSkuMaterialService.setSkuMaterialByContractCode(adminContractDetails);
		               
		        }
		    });
		
		
	}

	@Override
	public Message cancelContract(Long id, String operator, String cancelReason) {
		AdminContract adminContract = this.findById(id);
		adminContract.setContractStatus(ContractStatus.Cancel);
		adminContract.setUpdateBy(operator);
		adminContract.setCancelReason(cancelReason);
		adminContract.setUpdateTime(new Date());
		adminContract.setStatus(DataStatus.Valid);
		adminContractMapper.updateByPrimaryKey(adminContract);
		return Message.success("操作成功");
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		AdminContractExample example = new AdminContractExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		AdminContract record = new AdminContract();
		record.setStatus(DataStatus.Delete);
		return adminContractMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[] { id });
	}

	@Override
	public int saveOrUpdate(AdminContract adminContract, String operator) {
		int r = 0;
		if (adminContract.getId() != null) {
			r = this.update(adminContract, operator);
		} else {
			r = this.save(adminContract, operator);
		}
		return r;
	}

	@Override
	public ResultSet<Map<String, Object>> searchContractSettlement(QueryInfo queryInfo, String contractCode, String supplierName, ContractStatus contractStatus) {
		List<Map<String, Object>> list = adminContractMapper.selectContractSettlement(queryInfo, contractCode, supplierName, contractStatus == null ? null
				: contractStatus.name());
		int count = adminContractMapper.countSettlement(contractCode, supplierName, contractStatus == null ? null : contractStatus.name());
		ResultSet<Map<String, Object>> resultSet = new ResultSet<Map<String, Object>>(count, list);
		return resultSet;
	}

	@Override
	public List<AdminContractDetail> findDetail(Long cId) {
		AdminContractDetailExample example = new AdminContractDetailExample();
		example.createCriteria().andContractIdEqualTo(cId).andStatusEqualTo(DataStatus.Valid.name());
		return adminContractDetailMapper.selectByExample(example);
	}

	@Override
	public String findContractCode(String frameCode) {
		return adminContractMapper.findContractCode(frameCode);
	}
	

}
